// TerrainEditorDoc.cpp : implementation of the CTerrainEditorDoc class
//

#include "stdafx.h"
#include "TerrainEditor.h"
#include "TerrainEditorDoc.h"
#include "ImageTGA.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTerrainEditorDoc

IMPLEMENT_DYNCREATE(CTerrainEditorDoc, CDocument)

BEGIN_MESSAGE_MAP(CTerrainEditorDoc, CDocument)
	//{{AFX_MSG_MAP(CTerrainEditorDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTerrainEditorDoc construction/destruction

CTerrainEditorDoc::CTerrainEditorDoc()
{
}

CTerrainEditorDoc::~CTerrainEditorDoc()
{
}

BOOL CTerrainEditorDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CTerrainEditorDoc serialization

void CTerrainEditorDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CTerrainEditorDoc diagnostics

#ifdef _DEBUG
void CTerrainEditorDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CTerrainEditorDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTerrainEditorDoc commands

BOOL CTerrainEditorDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	if (m_Heightmap.m_HeightValues.m_pImageData == NULL)
	{
		AfxMessageBox("No image data is available to save.");
		return(FALSE);
	}
	
	// Save the terrain data

	int nRet = m_Heightmap.m_HeightValues.Save((char*)lpszPathName);

	// Save the ini file (terrain properties)

	CString sFilePath, sIniFilePath, sNewDocTitle;
	int nCursorPos, nFileLength;
	sFilePath = (char*)lpszPathName;
	nFileLength = sFilePath.GetLength();
	sIniFilePath = sFilePath.Left(nFileLength - 4) + "Properties.ini";
	nCursorPos = sFilePath.ReverseFind('\\') + 1;
	sNewDocTitle = sFilePath.Right(nFileLength - nCursorPos);

	m_IniFile.m_sPath = sIniFilePath;
	m_IniFile.DeleteIfExists();
	m_IniFile.WriteSection("Mesh Properties");
	m_IniFile.WriteKey("MinHeight", m_TerrainMesh.m_fMinHeight);
	m_IniFile.WriteKey("MaxHeight", m_TerrainMesh.m_fMaxHeight);
	m_IniFile.WriteKey("MeshSpacing", m_TerrainMesh.m_fMeshSpacing);

	// Update document title
	
	SetTitle(sNewDocTitle);

	// Update views

	UpdateAllViews(0);

	return(TRUE);
}

BOOL CTerrainEditorDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	
	// Load .tga image file

	int nRet = m_Heightmap.m_HeightValues.Load((char*)lpszPathName);

	// Load the .ini file

	CString sFilePath, sIniFilePath;
	sFilePath = (char*)lpszPathName;
	sIniFilePath = sFilePath.Left(sFilePath.GetLength() - 4) + "Properties.ini";
	m_IniFile.m_sPath = sIniFilePath;
	m_IniFile.LoadIniFile();

	// Assign values from ini file

	m_IniFile.ReadKey("Mesh Properties", "MinHeight", m_TerrainMesh.m_fMinHeight);
	m_IniFile.ReadKey("Mesh Properties", "MaxHeight", m_TerrainMesh.m_fMaxHeight);
	m_IniFile.ReadKey("Mesh Properties", "MeshSpacing", m_TerrainMesh.m_fMeshSpacing);

	// Load in texture set

	bool bTextureProblem = false;
	if (m_IniFile.m_Elevation.nNumTextures > 0)
	{
		m_imgElevation.resize(m_IniFile.m_Elevation.nNumTextures);
		for (int i=0; i<m_IniFile.m_Elevation.nNumTextures; i++)
		{
			if (m_imgElevation[i].Load(m_IniFile.m_Elevation.sTexturePath[i]) < 0)
			{
				AfxMessageBox("Cannot find " + m_IniFile.m_Elevation.sTexturePath[i] + "! Check the map .ini file.");
				bTextureProblem = true;
				break;
			}
		}
	}

	// Set booleans to alert views

	if (bTextureProblem == false)
	{
		m_bTerrainDataExists = true;
		m_b2DNewTerrainGenerated = true;
		m_b3DNewTerrainGenerated = true;
	}

	return(TRUE);
}

void CTerrainEditorDoc::CreateTerrainTexture()
{
	if (m_IniFile.m_Elevation.nNumTextures < 1) return;

	CImageTGA imgTerrain;
	imgTerrain.SetupUncomp24Bit(256);
	int index = 0;

	for (unsigned int i=0; i<m_TerrainMesh.m_nRows; i++)
	{
		for (unsigned int j=0; j<m_TerrainMesh.m_nCols; j++)
		{
			float fHeight = m_TerrainMesh.m_vVertexCoords[i][j].y;

			// Get the BGR values from each image

			float fBlue = 0.0f, fGreen = 0.0f, fRed = 0.0f;

			for (int i=0; i<m_IniFile.m_Elevation.nNumTextures; i++)
			{
				float fMinElevHeight = m_IniFile.m_Elevation.fMinPct[i] * 0.01f * m_TerrainMesh.m_fMaxHeight;
				float fMaxElevHeight = m_IniFile.m_Elevation.fMaxPct[i] * 0.01f * m_TerrainMesh.m_fMaxHeight;
				
				float fPercent;

				if (fHeight >= fMinElevHeight && fHeight <= fMaxElevHeight)
				{
					fPercent = (fHeight - fMinElevHeight) / (fMaxElevHeight - fMinElevHeight);
				}
				else
				{
					fPercent = 0.0f;
				}

				fBlue += fPercent * m_imgElevation[i].m_pImageData[index];
				fGreen += fPercent * m_imgElevation[i].m_pImageData[index+1];
				fRed += fPercent * m_imgElevation[i].m_pImageData[index+2];
			}
			
			if (fBlue > 255.0f) fBlue = 255.0f;
			if (fGreen > 255.0f) fGreen = 255.0f;
			if (fRed > 255.0f) fRed = 255.0f;

			imgTerrain.m_pImageData[index] = (unsigned char) fBlue;
			imgTerrain.m_pImageData[index+1] = (unsigned char) fGreen;
			imgTerrain.m_pImageData[index+2] = (unsigned char) fRed;

			index += 3;
		}
	}

	//imgTerrain.Save("c:\\txt.tga");
}
